<template>
    <div v-show="value" class="vue-image-crop-upload">
        <div class="vicp-wrap">
            <div class="vicp-close" @click="off">
                <i class="vicp-icon4" />
            </div>

            <div v-show="step == 1" class="vicp-step1">
                <div
                    class="vicp-drop-area"
                    @dragleave="preventDefault"
                    @dragover="preventDefault"
                    @dragenter="preventDefault"
                    @click="handleClick"
                    @drop="handleChange"
                >
                    <i v-show="loading != 1" class="vicp-icon1">
                        <i class="vicp-icon1-arrow" />
                        <i class="vicp-icon1-body" />
                        <i class="vicp-icon1-bottom" />
                    </i>
                    <span v-show="loading !== 1" class="vicp-hint">{{
                        lang.hint
                    }}</span>
                    <span
                        v-show="!isSupported"
                        class="vicp-no-supported-hint"
                        >{{ lang.noSupported }}</span
                    >
                    <input
                        v-show="false"
                        v-if="step == 1"
                        ref="fileinput"
                        type="file"
                        @change="handleChange"
                    />
                </div>
                <div v-show="hasError" class="vicp-error">
                    <i class="vicp-icon2" />
                    {{ errorMsg }}
                </div>
                <div class="vicp-operate">
                    <a @click="off" @mousedown="ripple">{{ lang.btn.off }}</a>
                </div>
            </div>

            <div v-if="step == 2" class="vicp-step2">
                <div class="vicp-crop">
                    <div v-show="true" class="vicp-crop-left">
                        <div class="vicp-img-container">
                            <img
                                ref="img"
                                :src="sourceImgUrl"
                                :style="sourceImgStyle"
                                class="vicp-img"
                                draggable="false"
                                @drag="preventDefault"
                                @dragstart="preventDefault"
                                @dragend="preventDefault"
                                @dragleave="preventDefault"
                                @dragover="preventDefault"
                                @dragenter="preventDefault"
                                @drop="preventDefault"
                                @touchstart="imgStartMove"
                                @touchmove="imgMove"
                                @touchend="createImg"
                                @touchcancel="createImg"
                                @mousedown="imgStartMove"
                                @mousemove="imgMove"
                                @mouseup="createImg"
                                @mouseout="createImg"
                            />
                            <div
                                :style="sourceImgShadeStyle"
                                class="vicp-img-shade vicp-img-shade-1"
                            />
                            <div
                                :style="sourceImgShadeStyle"
                                class="vicp-img-shade vicp-img-shade-2"
                            />
                        </div>

                        <div class="vicp-range">
                            <input
                                :value="scale.range"
                                type="range"
                                step="1"
                                min="0"
                                max="100"
                                @input="zoomChange"
                            />
                            <i
                                class="vicp-icon5"
                                @mousedown="startZoomSub"
                                @mouseout="endZoomSub"
                                @mouseup="endZoomSub"
                            />
                            <i
                                class="vicp-icon6"
                                @mousedown="startZoomAdd"
                                @mouseout="endZoomAdd"
                                @mouseup="endZoomAdd"
                            />
                        </div>

                        <div v-if="!noRotate" class="vicp-rotate">
                            <i
                                @mousedown="startRotateLeft"
                                @mouseout="endRotate"
                                @mouseup="endRotate"
                                >↺</i
                            >
                            <i
                                @mousedown="startRotateRight"
                                @mouseout="endRotate"
                                @mouseup="endRotate"
                                >↻</i
                            >
                        </div>
                    </div>
                    <div v-show="true" class="vicp-crop-right">
                        <div class="vicp-preview">
                            <div v-if="!noSquare" class="vicp-preview-item">
                                <img
                                    :src="createImgUrl"
                                    :style="previewStyle"
                                />
                                <span>{{ lang.preview }}</span>
                            </div>
                            <div
                                v-if="!noCircle"
                                class="
                                    vicp-preview-item vicp-preview-item-circle
                                "
                            >
                                <img
                                    :src="createImgUrl"
                                    :style="previewStyle"
                                />
                                <span>{{ lang.preview }}</span>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="vicp-operate">
                    <a @click="setStep(1)" @mousedown="ripple">{{
                        lang.btn.back
                    }}</a>
                    <a
                        class="vicp-operate-btn"
                        @click="prepareUpload"
                        @mousedown="ripple"
                        >{{ lang.btn.save }}</a
                    >
                </div>
            </div>

            <div v-if="step == 3" class="vicp-step3">
                <div class="vicp-upload">
                    <span v-show="loading === 1" class="vicp-loading">{{
                        lang.loading
                    }}</span>
                    <div class="vicp-progress-wrap">
                        <span
                            v-show="loading === 1"
                            :style="progressStyle"
                            class="vicp-progress"
                        />
                    </div>
                    <div v-show="hasError" class="vicp-error">
                        <i class="vicp-icon2" />
                        {{ errorMsg }}
                    </div>
                    <div v-show="loading === 2" class="vicp-success">
                        <i class="vicp-icon3" />
                        {{ lang.success }}
                    </div>
                </div>
                <div class="vicp-operate">
                    <a @click="setStep(2)" @mousedown="ripple">{{
                        lang.btn.back
                    }}</a>
                    <a @click="off" @mousedown="ripple">{{ lang.btn.close }}</a>
                </div>
            </div>
            <canvas
                v-show="false"
                ref="canvas"
                :width="width"
                :height="height"
            />
        </div>
    </div>
</template>

<script>
"use strict";
import request from "@/utils/request";
import language from "./utils/language.js";
import mimes from "./utils/mimes.js";
import data2blob from "./utils/data2blob.js";
import effectRipple from "./utils/effectRipple.js";
export default {
    props: {
        // 域，上传文件name，触发事件会带上（如果一个页面多个图片上传控件，可以做区分
        field: {
            type: String,
            default: "avatar",
        },
        // 原名key，类似于id，触发事件会带上（如果一个页面多个图片上传控件，可以做区分
        ki: {
            type: Number,
            default: 0,
        },
        // 显示该控件与否
        value: {
            type: Boolean,
            default: true,
        },
        // 上传地址
        url: {
            type: String,
            default: "",
        },
        // 其他要上传文件附带的数据，对象格式
        params: {
            type: Object,
            default: null,
        },
        // Add custom headers
        headers: {
            type: Object,
            default: null,
        },
        // 剪裁图片的宽
        width: {
            type: Number,
            default: 200,
        },
        // 剪裁图片的高
        height: {
            type: Number,
            default: 200,
        },
        // 不显示旋转功能
        noRotate: {
            type: Boolean,
            default: true,
        },
        // 不预览圆形图片
        noCircle: {
            type: Boolean,
            default: false,
        },
        // 不预览方形图片
        noSquare: {
            type: Boolean,
            default: false,
        },
        // 单文件大小限制
        maxSize: {
            type: Number,
            default: 10240,
        },
        // 语言类型
        langType: {
            type: String,
            default: "zh",
        },
        // 语言包
        langExt: {
            type: Object,
            default: null,
        },
        // 图片上传格式
        imgFormat: {
            type: String,
            default: "png",
        },
        // 是否支持跨域
        withCredentials: {
            type: Boolean,
            default: false,
        },
    },
    data() {
        const { imgFormat, langType, langExt, width, height } = this;
        let isSupported = true;
        const allowImgFormat = ["jpg", "png"];
        const tempImgFormat =
            allowImgFormat.indexOf(imgFormat) === -1 ? "jpg" : imgFormat;
        const lang = language[langType] ? language[langType] : language["en"];
        const mime = mimes[tempImgFormat];
        // 规范图片格式
        this.imgFormat = tempImgFormat;
        if (langExt) {
            Object.assign(lang, langExt);
        }
        if (typeof FormData !== "function") {
            isSupported = false;
        }
        return {
            // 图片的mime
            mime,
            // 语言包
            lang,
            // 浏览器是否支持该控件
            isSupported,
            // 浏览器是否支持触屏事件
            // eslint-disable-next-line no-prototype-builtins
            isSupportTouch: document.hasOwnProperty("ontouchstart"),
            // 步骤
            step: 1, // 1选择文件 2剪裁 3上传
            // 上传状态及进度
            loading: 0, // 0未开始 1正在 2成功 3错误
            progress: 0,
            // 是否有错误及错误信息
            hasError: false,
            errorMsg: "",
            // 需求图宽高比
            ratio: width / height,
            // 原图地址、生成图片地址
            sourceImg: null,
            sourceImgUrl: "",
            createImgUrl: "",
            // 原图片拖动事件初始值
            sourceImgMouseDown: {
                on: false,
                mX: 0, // 鼠标按下的坐标
                mY: 0,
                x: 0, // scale原图坐标
                y: 0,
            },
            // 生成图片预览的容器大小
            previewContainer: {
                width: 100,
                height: 100,
            },
            // 原图容器宽高
            sourceImgContainer: {
                // sic
                width: 240,
                height: 184, // 如果生成图比例与此一致会出现bug，先改成特殊的格式吧，哈哈哈
            },
            // 原图展示属性
            scale: {
                zoomAddOn: false, // 按钮缩放事件开启
                zoomSubOn: false, // 按钮缩放事件开启
                range: 1, // 最大100
                rotateLeft: false, // 按钮向左旋转事件开启
                rotateRight: false, // 按钮向右旋转事件开启
                degree: 0, // 旋转度数
                x: 0,
                y: 0,
                width: 0,
                height: 0,
                maxWidth: 0,
                maxHeight: 0,
                minWidth: 0, // 最宽
                minHeight: 0,
                naturalWidth: 0, // 原宽
                naturalHeight: 0,
            },
        };
    },
    computed: {
        // 进度条样式
        progressStyle() {
            const { progress } = this;
            return {
                width: progress + "%",
            };
        },
        // 原图样式
        sourceImgStyle() {
            const { scale, sourceImgMasking } = this;
            const top = scale.y + sourceImgMasking.y + "px";
            const left = scale.x + sourceImgMasking.x + "px";
            return {
                top,
                left,
                width: scale.width + "px",
                height: scale.height + "px",
                transform: "rotate(" + scale.degree + "deg)", // 旋转时 左侧原始图旋转样式
                "-ms-transform": "rotate(" + scale.degree + "deg)", // 兼容IE9
                "-moz-transform": "rotate(" + scale.degree + "deg)", // 兼容FireFox
                "-webkit-transform": "rotate(" + scale.degree + "deg)", // 兼容Safari 和 chrome
                "-o-transform": "rotate(" + scale.degree + "deg)", // 兼容 Opera
            };
        },
        // 原图蒙版属性
        sourceImgMasking() {
            const { width, height, ratio, sourceImgContainer } = this;
            const sic = sourceImgContainer;
            const sicRatio = sic.width / sic.height; // 原图容器宽高比
            let x = 0;
            let y = 0;
            let w = sic.width;
            let h = sic.height;
            let scale = 1;
            if (ratio < sicRatio) {
                scale = sic.height / height;
                w = sic.height * ratio;
                x = (sic.width - w) / 2;
            }
            if (ratio > sicRatio) {
                scale = sic.width / width;
                h = sic.width / ratio;
                y = (sic.height - h) / 2;
            }
            return {
                scale, // 蒙版相对需求宽高的缩放
                x,
                y,
                width: w,
                height: h,
            };
        },
        // 原图遮罩样式
        sourceImgShadeStyle() {
            const { sourceImgMasking, sourceImgContainer } = this;
            const sic = sourceImgContainer;
            const sim = sourceImgMasking;
            const w =
                sim.width === sic.width
                    ? sim.width
                    : (sic.width - sim.width) / 2;
            const h =
                sim.height === sic.height
                    ? sim.height
                    : (sic.height - sim.height) / 2;
            return {
                width: w + "px",
                height: h + "px",
            };
        },
        previewStyle() {
            const { ratio, previewContainer } = this;
            const pc = previewContainer;
            let w = pc.width;
            let h = pc.height;
            const pcRatio = w / h;
            if (ratio < pcRatio) {
                w = pc.height * ratio;
            }
            if (ratio > pcRatio) {
                h = pc.width / ratio;
            }
            return {
                width: w + "px",
                height: h + "px",
            };
        },
    },
    watch: {
        value(newValue) {
            if (newValue && this.loading !== 1) {
                this.reset();
            }
        },
    },
    created() {
        // 绑定按键esc隐藏此插件事件
        document.addEventListener("keyup", this.closeHandler);
    },
    destroyed() {
        document.removeEventListener("keyup", this.closeHandler);
    },
    methods: {
        // 点击波纹效果
        ripple(e) {
            effectRipple(e);
        },
        // 关闭控件
        off() {
            setTimeout(() => {
                this.$emit("input", false);
                this.$emit("close");
                if (this.step === 3 && this.loading === 2) {
                    this.setStep(1);
                }
            }, 200);
        },
        // 设置步骤
        setStep(no) {
            // 延时是为了显示动画效果呢，哈哈哈
            setTimeout(() => {
                this.step = no;
            }, 200);
        },
        /* 图片选择区域函数绑定
     ---------------------------------------------------------------*/
        preventDefault(e) {
            e.preventDefault();
            return false;
        },
        handleClick(e) {
            if (this.loading !== 1) {
                if (e.target !== this.$refs.fileinput) {
                    e.preventDefault();
                    if (document.activeElement !== this.$refs) {
                        this.$refs.fileinput.click();
                    }
                }
            }
        },
        handleChange(e) {
            e.preventDefault();
            if (this.loading !== 1) {
                const files = e.target.files || e.dataTransfer.files;
                this.reset();
                if (this.checkFile(files[0])) {
                    this.setSourceImg(files[0]);
                }
            }
        },
        /* ---------------------------------------------------------------*/
        // 检测选择的文件是否合适
        checkFile(file) {
            const { lang, maxSize } = this;
            // 仅限图片
            if (file.type.indexOf("image") === -1) {
                this.hasError = true;
                this.errorMsg = lang.error.onlyImg;
                return false;
            }
            // 超出大小
            if (file.size / 1024 > maxSize) {
                this.hasError = true;
                this.errorMsg = lang.error.outOfSize + maxSize + "kb";
                return false;
            }
            return true;
        },
        // 重置控件
        reset() {
            this.loading = 0;
            this.hasError = false;
            this.errorMsg = "";
            this.progress = 0;
        },
        // 设置图片源
        setSourceImg(file) {
            const fr = new FileReader();
            fr.onload = (e) => {
                this.sourceImgUrl = fr.result;
                this.startCrop();
            };
            fr.readAsDataURL(file);
        },
        // 剪裁前准备工作
        startCrop() {
            const {
                width,
                height,
                ratio,
                scale,
                sourceImgUrl,
                sourceImgMasking,
                lang,
            } = this;
            const sim = sourceImgMasking;
            const img = new Image();
            img.src = sourceImgUrl;
            img.onload = () => {
                const nWidth = img.naturalWidth;
                const nHeight = img.naturalHeight;
                const nRatio = nWidth / nHeight;
                let w = sim.width;
                let h = sim.height;
                let x = 0;
                let y = 0;
                // 图片像素不达标
                if (nWidth < width || nHeight < height) {
                    this.hasError = true;
                    this.errorMsg = lang.error.lowestPx + width + "*" + height;
                    return false;
                }
                if (ratio > nRatio) {
                    h = w / nRatio;
                    y = (sim.height - h) / 2;
                }
                if (ratio < nRatio) {
                    w = h * nRatio;
                    x = (sim.width - w) / 2;
                }
                scale.range = 0;
                scale.x = x;
                scale.y = y;
                scale.width = w;
                scale.height = h;
                scale.degree = 0;
                scale.minWidth = w;
                scale.minHeight = h;
                scale.maxWidth = nWidth * sim.scale;
                scale.maxHeight = nHeight * sim.scale;
                scale.naturalWidth = nWidth;
                scale.naturalHeight = nHeight;
                this.sourceImg = img;
                this.createImg();
                this.setStep(2);
            };
        },
        // 鼠标按下图片准备移动
        imgStartMove(e) {
            e.preventDefault();
            // 支持触摸事件，则鼠标事件无效
            if (this.isSupportTouch && !e.targetTouches) {
                return false;
            }
            const et = e.targetTouches ? e.targetTouches[0] : e;
            const { sourceImgMouseDown, scale } = this;
            const simd = sourceImgMouseDown;
            simd.mX = et.screenX;
            simd.mY = et.screenY;
            simd.x = scale.x;
            simd.y = scale.y;
            simd.on = true;
        },
        // 鼠标按下状态下移动，图片移动
        imgMove(e) {
            e.preventDefault();
            // 支持触摸事件，则鼠标事件无效
            if (this.isSupportTouch && !e.targetTouches) {
                return false;
            }
            const et = e.targetTouches ? e.targetTouches[0] : e;
            const {
                sourceImgMouseDown: { on, mX, mY, x, y },
                scale,
                sourceImgMasking,
            } = this;
            const sim = sourceImgMasking;
            const nX = et.screenX;
            const nY = et.screenY;
            const dX = nX - mX;
            const dY = nY - mY;
            let rX = x + dX;
            let rY = y + dY;
            if (!on) return;
            if (rX > 0) {
                rX = 0;
            }
            if (rY > 0) {
                rY = 0;
            }
            if (rX < sim.width - scale.width) {
                rX = sim.width - scale.width;
            }
            if (rY < sim.height - scale.height) {
                rY = sim.height - scale.height;
            }
            scale.x = rX;
            scale.y = rY;
        },
        // 按钮按下开始向右旋转
        startRotateRight(e) {
            const { scale } = this;
            scale.rotateRight = true;
            const rotate = () => {
                if (scale.rotateRight) {
                    const degree = ++scale.degree;
                    this.createImg(degree);
                    setTimeout(function () {
                        rotate();
                    }, 60);
                }
            };
            rotate();
        },
        // 按钮按下开始向左旋转
        startRotateLeft(e) {
            const { scale } = this;
            scale.rotateLeft = true;
            const rotate = () => {
                if (scale.rotateLeft) {
                    const degree = --scale.degree;
                    this.createImg(degree);
                    setTimeout(function () {
                        rotate();
                    }, 60);
                }
            };
            rotate();
        },
        // 停止旋转
        endRotate() {
            const { scale } = this;
            scale.rotateLeft = false;
            scale.rotateRight = false;
        },
        // 按钮按下开始放大
        startZoomAdd(e) {
            const { scale } = this;
            scale.zoomAddOn = true;
            const zoom = () => {
                if (scale.zoomAddOn) {
                    const range = scale.range >= 100 ? 100 : ++scale.range;
                    this.zoomImg(range);
                    setTimeout(function () {
                        zoom();
                    }, 60);
                }
            };
            zoom();
        },
        // 按钮松开或移开取消放大
        endZoomAdd(e) {
            this.scale.zoomAddOn = false;
        },
        // 按钮按下开始缩小
        startZoomSub(e) {
            const { scale } = this;
            scale.zoomSubOn = true;
            const zoom = () => {
                if (scale.zoomSubOn) {
                    const range = scale.range <= 0 ? 0 : --scale.range;
                    this.zoomImg(range);
                    setTimeout(function () {
                        zoom();
                    }, 60);
                }
            };
            zoom();
        },
        // 按钮松开或移开取消缩小
        endZoomSub(e) {
            const { scale } = this;
            scale.zoomSubOn = false;
        },
        zoomChange(e) {
            this.zoomImg(e.target.value);
        },
        // 缩放原图
        zoomImg(newRange) {
            const { sourceImgMasking, scale } = this;
            const {
                maxWidth,
                maxHeight,
                minWidth,
                minHeight,
                width,
                height,
                x,
                y,
            } = scale;
            const sim = sourceImgMasking;
            // 蒙版宽高
            const sWidth = sim.width;
            const sHeight = sim.height;
            // 新宽高
            const nWidth = minWidth + ((maxWidth - minWidth) * newRange) / 100;
            const nHeight =
                minHeight + ((maxHeight - minHeight) * newRange) / 100;
            // 新坐标（根据蒙版中心点缩放）
            let nX = sWidth / 2 - (nWidth / width) * (sWidth / 2 - x);
            let nY = sHeight / 2 - (nHeight / height) * (sHeight / 2 - y);
            // 判断新坐标是否超过蒙版限制
            if (nX > 0) {
                nX = 0;
            }
            if (nY > 0) {
                nY = 0;
            }
            if (nX < sWidth - nWidth) {
                nX = sWidth - nWidth;
            }
            if (nY < sHeight - nHeight) {
                nY = sHeight - nHeight;
            }
            // 赋值处理
            scale.x = nX;
            scale.y = nY;
            scale.width = nWidth;
            scale.height = nHeight;
            scale.range = newRange;
            setTimeout(() => {
                if (scale.range === newRange) {
                    this.createImg();
                }
            }, 300);
        },
        // 生成需求图片
        createImg(e) {
            const {
                mime,
                sourceImg,
                scale: { x, y, width, height, degree },
                sourceImgMasking: { scale },
            } = this;
            const canvas = this.$refs.canvas;
            const ctx = canvas.getContext("2d");
            if (e) {
                // 取消鼠标按下移动状态
                this.sourceImgMouseDown.on = false;
            }
            canvas.width = this.width;
            canvas.height = this.height;
            ctx.clearRect(0, 0, this.width, this.height);
            // 将透明区域设置为白色底边
            ctx.fillStyle = "#fff";
            ctx.fillRect(0, 0, this.width, this.height);
            ctx.translate(this.width * 0.5, this.height * 0.5);
            ctx.rotate((Math.PI * degree) / 180);
            ctx.translate(-this.width * 0.5, -this.height * 0.5);
            ctx.drawImage(
                sourceImg,
                x / scale,
                y / scale,
                width / scale,
                height / scale
            );
            this.createImgUrl = canvas.toDataURL(mime);
        },
        prepareUpload() {
            const { url, createImgUrl, field, ki } = this;
            this.$emit("crop-success", createImgUrl, field, ki);
            if (typeof url === "string" && url) {
                this.upload();
            } else {
                this.off();
            }
        },
        // 上传图片
        upload() {
            const {
                lang,
                imgFormat,
                mime,
                url,
                params,
                field,
                ki,
                createImgUrl,
            } = this;
            const fmData = new FormData();
            fmData.append(
                field,
                data2blob(createImgUrl, mime),
                field + "." + imgFormat
            );
            // 添加其他参数
            if (typeof params === "object" && params) {
                Object.keys(params).forEach((k) => {
                    fmData.append(k, params[k]);
                });
            }
            // 监听进度回调
            // const uploadProgress = (event) => {
            //   if (event.lengthComputable) {
            //     this.progress = 100 * Math.round(event.loaded) / event.total
            //   }
            // }
            // 上传文件
            this.reset();
            this.loading = 1;
            this.setStep(3);
            // console.log(createImgUrl);
            // var file = this.base64ToFile(createImgUrl, "adminFace");
            request({
                url,
                method: "post",
                // file: file,
                // data: fmData,
                data: {
                    base64File: createImgUrl
                }
            })
                .then((resData) => {
                    this.loading = 2;
                    this.$emit("crop-upload-success", resData.data);
                })
                .catch((err) => {
                    if (this.value) {
                        this.loading = 3;
                        this.hasError = true;
                        this.errorMsg = lang.fail;
                        this.$emit("crop-upload-fail", err, field, ki);
                    }
                });
        },

        base64ToFile(base64, fileName) {
            let arr = base64.split(',');
            let mime = arr[0].match(/:(.*?);/)[1];
            let bytes = atob(arr[1]);
            let n = bytes.length
            let ia = new Uint8Array(n);
            while (n--) {
                ia[n] = bytes.charCodeAt(n);
            }
            return new File([ia], fileName, { type: mime });
        },

        closeHandler(e) {
            if (this.value && (e.key === "Escape" || e.keyCode === 27)) {
                this.off();
            }
        },
    },
};
</script>

<style lang="scss">
@charset "UTF-8";
@-webkit-keyframes vicp_progress {
    0% {
        background-position-y: 0;
    }
    100% {
        background-position-y: 40px;
    }
}
@keyframes vicp_progress {
    0% {
        background-position-y: 0;
    }
    100% {
        background-position-y: 40px;
    }
}
@-webkit-keyframes vicp {
    0% {
        opacity: 0;
        -webkit-transform: scale(0) translatey(-60px);
        transform: scale(0) translatey(-60px);
    }
    100% {
        opacity: 1;
        -webkit-transform: scale(1) translatey(0);
        transform: scale(1) translatey(0);
    }
}
@keyframes vicp {
    0% {
        opacity: 0;
        -webkit-transform: scale(0) translatey(-60px);
        transform: scale(0) translatey(-60px);
    }
    100% {
        opacity: 1;
        -webkit-transform: scale(1) translatey(0);
        transform: scale(1) translatey(0);
    }
}
.vue-image-crop-upload {
    position: fixed;
    display: block;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    z-index: 10000;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.65);
    -webkit-tap-highlight-color: transparent;
    -moz-tap-highlight-color: transparent;
}
.vue-image-crop-upload .vicp-wrap {
    -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
    position: fixed;
    display: block;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    z-index: 10000;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    width: 600px;
    height: 330px;
    padding: 25px;
    background-color: #fff;
    border-radius: 2px;
    -webkit-animation: vicp 0.12s ease-in;
    animation: vicp 0.12s ease-in;
}
.vue-image-crop-upload .vicp-wrap .vicp-close {
    position: absolute;
    right: -30px;
    top: -30px;
}
.vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4 {
    position: relative;
    display: block;
    width: 30px;
    height: 30px;
    cursor: pointer;
    -webkit-transition: -webkit-transform 0.18s;
    transition: -webkit-transform 0.18s;
    transition: transform 0.18s;
    transition: transform 0.18s, -webkit-transform 0.18s;
    -webkit-transform: rotate(0);
    -ms-transform: rotate(0);
    transform: rotate(0);
}
.vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4::after,
.vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4::before {
    -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
    content: "";
    position: absolute;
    top: 12px;
    left: 4px;
    width: 20px;
    height: 3px;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    transform: rotate(45deg);
    background-color: #fff;
}
.vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4::after {
    -webkit-transform: rotate(-45deg);
    -ms-transform: rotate(-45deg);
    transform: rotate(-45deg);
}
.vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4:hover {
    -webkit-transform: rotate(90deg);
    -ms-transform: rotate(90deg);
    transform: rotate(90deg);
}
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area {
    position: relative;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    padding: 35px;
    height: 170px;
    background-color: rgba(0, 0, 0, 0.03);
    text-align: center;
    border: 1px dashed rgba(0, 0, 0, 0.08);
    overflow: hidden;
}
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area .vicp-icon1 {
    display: block;
    margin: 0 auto 6px;
    width: 42px;
    height: 42px;
    overflow: hidden;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step1
    .vicp-drop-area
    .vicp-icon1
    .vicp-icon1-arrow {
    display: block;
    margin: 0 auto;
    width: 0;
    height: 0;
    border-bottom: 14.7px solid rgba(0, 0, 0, 0.3);
    border-left: 14.7px solid transparent;
    border-right: 14.7px solid transparent;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step1
    .vicp-drop-area
    .vicp-icon1
    .vicp-icon1-body {
    display: block;
    width: 12.6px;
    height: 14.7px;
    margin: 0 auto;
    background-color: rgba(0, 0, 0, 0.3);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step1
    .vicp-drop-area
    .vicp-icon1
    .vicp-icon1-bottom {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    display: block;
    height: 12.6px;
    border: 6px solid rgba(0, 0, 0, 0.3);
    border-top: none;
}
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area .vicp-hint {
    display: block;
    padding: 15px;
    font-size: 14px;
    color: #666;
    line-height: 30px;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step1
    .vicp-drop-area
    .vicp-no-supported-hint {
    display: block;
    position: absolute;
    top: 0;
    left: 0;
    padding: 30px;
    width: 100%;
    height: 60px;
    line-height: 30px;
    background-color: #eee;
    text-align: center;
    color: #666;
    font-size: 14px;
}
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area:hover {
    cursor: pointer;
    border-color: rgba(0, 0, 0, 0.1);
    background-color: rgba(0, 0, 0, 0.05);
}
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop {
    overflow: hidden;
}
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left {
    float: left;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-img-container {
    position: relative;
    display: block;
    width: 240px;
    height: 180px;
    background-color: #e5e5e0;
    overflow: hidden;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-img-container
    .vicp-img {
    position: absolute;
    display: block;
    cursor: move;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-img-container
    .vicp-img-shade {
    -webkit-box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
    box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
    position: absolute;
    background-color: rgba(241, 242, 243, 0.8);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-img-container
    .vicp-img-shade.vicp-img-shade-1 {
    top: 0;
    left: 0;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-img-container
    .vicp-img-shade.vicp-img-shade-2 {
    bottom: 0;
    right: 0;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-rotate {
    position: relative;
    width: 240px;
    height: 18px;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-rotate
    i {
    display: block;
    width: 18px;
    height: 18px;
    border-radius: 100%;
    line-height: 18px;
    text-align: center;
    font-size: 12px;
    font-weight: bold;
    background-color: rgba(0, 0, 0, 0.08);
    color: #fff;
    overflow: hidden;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-rotate
    i:hover {
    -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
    cursor: pointer;
    background-color: rgba(0, 0, 0, 0.14);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-rotate
    i:first-child {
    float: left;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-rotate
    i:last-child {
    float: right;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range {
    position: relative;
    margin: 30px 0 10px 0;
    width: 240px;
    height: 18px;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    .vicp-icon5,
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    .vicp-icon6 {
    position: absolute;
    top: 0;
    width: 18px;
    height: 18px;
    border-radius: 100%;
    background-color: rgba(0, 0, 0, 0.08);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    .vicp-icon5:hover,
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    .vicp-icon6:hover {
    -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
    cursor: pointer;
    background-color: rgba(0, 0, 0, 0.14);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    .vicp-icon5 {
    left: 0;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    .vicp-icon5::before {
    position: absolute;
    content: "";
    display: block;
    left: 3px;
    top: 8px;
    width: 12px;
    height: 2px;
    background-color: #fff;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    .vicp-icon6 {
    right: 0;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    .vicp-icon6::before {
    position: absolute;
    content: "";
    display: block;
    left: 3px;
    top: 8px;
    width: 12px;
    height: 2px;
    background-color: #fff;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    .vicp-icon6::after {
    position: absolute;
    content: "";
    display: block;
    top: 3px;
    left: 8px;
    width: 2px;
    height: 12px;
    background-color: #fff;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"] {
    display: block;
    padding-top: 5px;
    margin: 0 auto;
    width: 180px;
    height: 8px;
    vertical-align: top;
    background: transparent;
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    cursor: pointer;
    /* 滑块
               ---------------------------------------------------------------*/
    /* 轨道
               ---------------------------------------------------------------*/
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]:focus {
    outline: none;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]::-webkit-slider-thumb {
    -webkit-box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
    box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
    -webkit-appearance: none;
    appearance: none;
    margin-top: -3px;
    width: 12px;
    height: 12px;
    background-color: #61c091;
    border-radius: 100%;
    border: none;
    -webkit-transition: 0.2s;
    transition: 0.2s;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]::-moz-range-thumb {
    box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
    -moz-appearance: none;
    appearance: none;
    width: 12px;
    height: 12px;
    background-color: #61c091;
    border-radius: 100%;
    border: none;
    -webkit-transition: 0.2s;
    transition: 0.2s;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]::-ms-thumb {
    box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
    appearance: none;
    width: 12px;
    height: 12px;
    background-color: #61c091;
    border: none;
    border-radius: 100%;
    -webkit-transition: 0.2s;
    transition: 0.2s;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]:active::-moz-range-thumb {
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
    width: 14px;
    height: 14px;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]:active::-ms-thumb {
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
    width: 14px;
    height: 14px;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]:active::-webkit-slider-thumb {
    -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
    margin-top: -4px;
    width: 14px;
    height: 14px;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]::-webkit-slider-runnable-track {
    -webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
    width: 100%;
    height: 6px;
    cursor: pointer;
    border-radius: 2px;
    border: none;
    background-color: rgba(68, 170, 119, 0.3);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]::-moz-range-track {
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
    width: 100%;
    height: 6px;
    cursor: pointer;
    border-radius: 2px;
    border: none;
    background-color: rgba(68, 170, 119, 0.3);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]::-ms-track {
    box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
    width: 100%;
    cursor: pointer;
    background: transparent;
    border-color: transparent;
    color: transparent;
    height: 6px;
    border-radius: 2px;
    border: none;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]::-ms-fill-lower {
    background-color: rgba(68, 170, 119, 0.3);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]::-ms-fill-upper {
    background-color: rgba(68, 170, 119, 0.15);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]:focus::-webkit-slider-runnable-track {
    background-color: rgba(68, 170, 119, 0.5);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]:focus::-moz-range-track {
    background-color: rgba(68, 170, 119, 0.5);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]:focus::-ms-fill-lower {
    background-color: rgba(68, 170, 119, 0.45);
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-left
    .vicp-range
    input[type="range"]:focus::-ms-fill-upper {
    background-color: rgba(68, 170, 119, 0.25);
}
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-right {
    float: right;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-right
    .vicp-preview {
    height: 150px;
    overflow: hidden;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-right
    .vicp-preview
    .vicp-preview-item {
    position: relative;
    padding: 5px;
    width: 100px;
    height: 100px;
    float: left;
    margin-right: 16px;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-right
    .vicp-preview
    .vicp-preview-item
    span {
    position: absolute;
    bottom: -30px;
    width: 100%;
    font-size: 14px;
    color: #bbb;
    display: block;
    text-align: center;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-right
    .vicp-preview
    .vicp-preview-item
    img {
    position: absolute;
    display: block;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    padding: 3px;
    background-color: #fff;
    border: 1px solid rgba(0, 0, 0, 0.15);
    overflow: hidden;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-right
    .vicp-preview
    .vicp-preview-item.vicp-preview-item-circle {
    margin-right: 0;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step2
    .vicp-crop
    .vicp-crop-right
    .vicp-preview
    .vicp-preview-item.vicp-preview-item-circle
    img {
    border-radius: 100%;
}
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload {
    position: relative;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    padding: 35px;
    height: 170px;
    background-color: rgba(0, 0, 0, 0.03);
    text-align: center;
    border: 1px dashed #ddd;
}
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-loading {
    display: block;
    padding: 15px;
    font-size: 16px;
    color: #999;
    line-height: 30px;
}
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-progress-wrap {
    margin-top: 12px;
    background-color: rgba(0, 0, 0, 0.08);
    border-radius: 3px;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step3
    .vicp-upload
    .vicp-progress-wrap
    .vicp-progress {
    position: relative;
    display: block;
    height: 5px;
    border-radius: 3px;
    background-color: #4a7;
    -webkit-box-shadow: 0 2px 6px 0 rgba(68, 170, 119, 0.3);
    box-shadow: 0 2px 6px 0 rgba(68, 170, 119, 0.3);
    -webkit-transition: width 0.15s linear;
    transition: width 0.15s linear;
    background-image: -webkit-linear-gradient(
        135deg,
        rgba(255, 255, 255, 0.2) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.2) 50%,
        rgba(255, 255, 255, 0.2) 75%,
        transparent 75%,
        transparent
    );
    background-image: linear-gradient(
        -45deg,
        rgba(255, 255, 255, 0.2) 25%,
        transparent 25%,
        transparent 50%,
        rgba(255, 255, 255, 0.2) 50%,
        rgba(255, 255, 255, 0.2) 75%,
        transparent 75%,
        transparent
    );
    background-size: 40px 40px;
    -webkit-animation: vicp_progress 0.5s linear infinite;
    animation: vicp_progress 0.5s linear infinite;
}
.vue-image-crop-upload
    .vicp-wrap
    .vicp-step3
    .vicp-upload
    .vicp-progress-wrap
    .vicp-progress::after {
    content: "";
    position: absolute;
    display: block;
    top: -3px;
    right: -3px;
    width: 9px;
    height: 9px;
    border: 1px solid rgba(245, 246, 247, 0.7);
    -webkit-box-shadow: 0 1px 4px 0 rgba(68, 170, 119, 0.7);
    box-shadow: 0 1px 4px 0 rgba(68, 170, 119, 0.7);
    border-radius: 100%;
    background-color: #4a7;
}
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-error,
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-success {
    height: 100px;
    line-height: 100px;
}
.vue-image-crop-upload .vicp-wrap .vicp-operate {
    position: absolute;
    right: 20px;
    bottom: 20px;
}
.vue-image-crop-upload .vicp-wrap .vicp-operate a {
    position: relative;
    float: left;
    display: block;
    margin-left: 10px;
    width: 100px;
    height: 36px;
    line-height: 36px;
    text-align: center;
    cursor: pointer;
    font-size: 14px;
    color: #4a7;
    border-radius: 2px;
    overflow: hidden;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.vue-image-crop-upload .vicp-wrap .vicp-operate a:hover {
    background-color: rgba(0, 0, 0, 0.03);
}
.vue-image-crop-upload .vicp-wrap .vicp-error,
.vue-image-crop-upload .vicp-wrap .vicp-success {
    display: block;
    font-size: 14px;
    line-height: 24px;
    height: 24px;
    color: #d10;
    text-align: center;
    vertical-align: top;
}
.vue-image-crop-upload .vicp-wrap .vicp-success {
    color: #4a7;
}
.vue-image-crop-upload .vicp-wrap .vicp-icon3 {
    position: relative;
    display: inline-block;
    width: 20px;
    height: 20px;
    top: 4px;
}
.vue-image-crop-upload .vicp-wrap .vicp-icon3::after {
    position: absolute;
    top: 3px;
    left: 6px;
    width: 6px;
    height: 10px;
    border-width: 0 2px 2px 0;
    border-color: #4a7;
    border-style: solid;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    transform: rotate(45deg);
    content: "";
}
.vue-image-crop-upload .vicp-wrap .vicp-icon2 {
    position: relative;
    display: inline-block;
    width: 20px;
    height: 20px;
    top: 4px;
}
.vue-image-crop-upload .vicp-wrap .vicp-icon2::after,
.vue-image-crop-upload .vicp-wrap .vicp-icon2::before {
    content: "";
    position: absolute;
    top: 9px;
    left: 4px;
    width: 13px;
    height: 2px;
    background-color: #d10;
    -webkit-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
    transform: rotate(45deg);
}
.vue-image-crop-upload .vicp-wrap .vicp-icon2::after {
    -webkit-transform: rotate(-45deg);
    -ms-transform: rotate(-45deg);
    transform: rotate(-45deg);
}
.e-ripple {
    position: absolute;
    border-radius: 100%;
    background-color: rgba(0, 0, 0, 0.15);
    background-clip: padding-box;
    pointer-events: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    -webkit-transform: scale(0);
    -ms-transform: scale(0);
    transform: scale(0);
    opacity: 1;
}
.e-ripple.z-active {
    opacity: 0;
    -webkit-transform: scale(2);
    -ms-transform: scale(2);
    transform: scale(2);
    -webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
    transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
    transition: opacity 1.2s ease-out, transform 0.6s ease-out;
    transition: opacity 1.2s ease-out, transform 0.6s ease-out,
        -webkit-transform 0.6s ease-out;
}
</style>
